﻿using System;
using System.Collections.Generic;
using GameFramework.Battle.Core;
using Gameplay.PVE.Utils;
using RootMotion.FinalIK;
using UnityEngine;
using Yoozoo.Managers;
using Yoozoo.UI.YGUI;

namespace Gameplay.PVE.Survivor
{
    public class HudComponent : ComponentBase
    {
        private BattleHudObject hudObject;

        private GameObject bossSign;
        private GameObject hpBar;
        private YImage hpBarImage;
        private YImage mpBarImage;
        private YImage shieldBarImage;
        private GameObject shieldRoot;
        private Canvas canvas;

        private GameObject mpBar;

        private bool forwardReady = false;

        private HudBubble bubble;
        private bool hasShownHp;

        private HudChatBubble chatBubble;
        private float chatBubbleTimer;
        private float chatBubbleDuration = 3f;

        private int hudResId;
        
        private Vector3 localPos  =  new Vector3(0, 2.3f, 0);

        private bool showBattleHud = true;

        protected override void OnInitialized()
        {
            CreateHud();
        }

        private void CreateHud()
        {
            hasShownHp = false;
            hudResId = (int)EBattleResId.Hud;
            if (unit.config != null && unit.config.IsBossHud())
            {
                hudResId = (int)EBattleResId.HudBoss;
            }
            hudObject = BattlePoolManager.Instance.GetHud(hudResId);
            hudObject.SetPrefabReadyAction(OnHudReady);
            hudObject.Parent = unit.Root.transform;
            hudObject.LocalPosition = localPos + new Vector3(0, unit.hudOffset, 0);
        }

        private void OnHudReady(GameObject gameObject)
        {
            canvas = gameObject.GetComponent<Canvas>();
            var mp = gameObject.transform.Find("bg/bgMp");
            mp.gameObject.SetActive(false);
            mpBar = mp.gameObject;
            var hpRoot = gameObject.transform.Find("bg/bgHp");
            var selfHpBar = hpRoot.Find("hpSelf").gameObject;
            var enemyHpBar = hpRoot.Find("hpEnemy").gameObject;
            shieldRoot = gameObject.transform.Find("bg/bgShield").gameObject;
            var shieldBar = shieldRoot.transform.Find("shield");
            if (unit.team == 0 || unit.team == 3)
            {
                hpBar = selfHpBar;
                selfHpBar.SetActive(true);
                enemyHpBar.SetActive(false);
            }
            else
            {
                hpBar = enemyHpBar;
                selfHpBar.SetActive(false);
                enemyHpBar.SetActive(true);
            }

            shieldBarImage = shieldBar.GetComponent<YImage>();

            mpBarImage = mp.Find("mp").GetComponent<YImage>();
            hpBarImage = hpBar.GetComponent<YImage>();
            gameObject.SetActive(false);
            gameObject.transform.localScale = new Vector3(0.015f, 0.015f, 0.015f);
            UpdateHpProgress(unit.currentHp / (float)unit.totalHp);
            UpdateShieldProgress(unit.shieldValue / (float)unit.totalHp);
            if (unit.HasMainSkill())
            {
                UpdateMpProgress(unit.currentMp / (float)unit.totalMp);
            }
        }

        protected override void OnUpdate()
        {
            if (chatBubbleTimer > 0)
            {
                var curDuration = TimeManager.time - chatBubbleTimer;
                if (curDuration >= chatBubbleDuration)
                {
                    HideChatBubble();
                }
            }
        }

        private void UpdateCameraForward(bool force = false)
        {
            if ((!forwardReady || force) && CameraManager.Instance.CameraReady && canvas != null)
            {
                hudObject.Forward = CameraManager.Instance.CameraForward;
                canvas.worldCamera = CameraManager.Instance.HudCamera;
                forwardReady = true;
            }
        }

        private void ShowHpBar()
        {
            if (showBattleHud)
            {
                hudObject.Active = true;
            }
            HideBubble();
        }

        public void HideBubble()
        {
            if (bubble != null)
            {
                //bubble.Hide();
                bubble.Destroy();
                ClassManager.Free(bubble);
                bubble = null;
            }
        }

        public void ShowBubble()
        {
            if (unit.isDead)
            {
                return;
            }
            if ( bubble == null)
            {
                bubble = ClassManager.Get<HudBubble>();
                bubble.Create(this.unit);
            }

            bubble.Show();
        }

        public void ShowChatBubble(string content, int type)
        {
            if (chatBubbleTimer != 0)
            {
                chatBubbleTimer = 0;
            }
            if (chatBubble == null)
            {
                chatBubble = ClassManager.Get<HudChatBubble>();
                chatBubble.Create(this.unit);
            }
            chatBubble.Show(content, type);
        }

        public void ShowChatBubbleDuration(string content, int type, float duration)
        {
            if (chatBubbleTimer > 0 || (chatBubble != null && chatBubble.IsShow == true))
            {
                return;
            }
            ShowChatBubble(content, type);
            if (duration > 0)
            {
                chatBubbleTimer = TimeManager.time;
                chatBubbleDuration = duration;
            }
        }

        public void HideChatBubble()
        {
            if (chatBubble != null)
            {
                chatBubble.Hide();
                chatBubble.Destroy();
                ClassManager.Free(chatBubble);
                chatBubble = null;
            }
            chatBubbleTimer = 0;
        }

        public void UpdateHpProgress(float percent)
        {
            if (hudObject == null)
            {
                return;
            }

            if (!hudObject.IsReady)
            {
                return;
            }

            if (percent < 1)
            {
                if (!hasShownHp)
                {
                    hasShownHp = true;
                    UpdateCameraForward();
                    ShowHpBar();
                }
            }

            hpBarImage.fillAmount = percent;
            //hpBarTempImage.fillAmount = percent;
        }

        public void UpdateShieldProgress(float percent)
        {
            if (hudObject == null)
            {
                return;
            }

            if (!hudObject.IsReady)
            {
                return;
            }

            shieldRoot.SetActive(percent > 0);
            shieldBarImage.fillAmount = percent;
            //hpBarTempImage.fillAmount = percent;
        }

        public void UpdateMpProgress(float percent)
        {
            if (hudObject == null)
            {
                return;
            }

            if (!hudObject.IsReady)
            {
                return;
            }

            if (percent > 0)
            {
                if (!mpBar.activeInHierarchy)
                {
                    mpBar.SetActive(true);
                    hasShownHp = true;
                    UpdateCameraForward();
                    ShowHpBar();
                }
            }

            mpBarImage.fillAmount = percent;
        }

        public void OnCameraChanged()
        {
            if (hudObject != null && hudObject.Active)
            {
                forwardReady = false;
                UpdateCameraForward(true);
            }
        }

        protected override void OnDead()
        {
            base.OnDead();
            Clear();
        }

        private void Clear()
        {
            if (hudObject != null)
            {
                BattlePoolManager.Instance.ReleaseHud(hudObject);
                hudObject = null;
            }

            HideBubble();
        }

       public void SetShowHud(bool isShow)
        {
            showBattleHud = isShow;
            if (hudObject != null)
            {
                hudObject.Active = isShow;
                if (isShow)
                {
                    UpdateCameraForward(true);
                }
            }
        }
        public override void OnReset()
        {
            Clear();
            forwardReady = false;
            canvas = null;
            bossSign = null;
            hpBar = null;
            hpBarImage = null;
            mpBarImage = null;
            shieldBarImage = null;
            shieldRoot = null;
            mpBar = null;
            HideChatBubble();
            HideBubble();
            hasShownHp = false;
            hudResId = 0;
            showBattleHud = true;
        }
    }
}